package jsontool

import (
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
)

type JObject struct {
	data map[string]interface{}
}

func (o *JObject) New(data []byte) error {
	o.data = make(map[string]interface{})

	return json.Unmarshal(data, &o.data)
}

func (o *JObject) Get(key string) (interface{}, error) {
	if v, ok := o.data[key]; ok {
		return v, nil
	} else {
		return nil, errors.New("no field")
	}
}

func (o *JObject) GetJObject(key string) (*JObject, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(map[string]interface{}); ok1 {
			d := &JObject{}
			d.data = v1
			return d, nil
		} else {
			return nil, errors.New("not JObject")
		}
	} else {
		return nil, errors.New("no field")
	}
}

func (o *JObject) GetJArray(key string) ([]JObject, error) {
	if v, ok := o.data[key]; ok {
		fmt.Printf("%+v\n", reflect.TypeOf(v))
		if vv, kk := v.([]interface{}); kk {
			fmt.Printf("vv :%v\n", vv)
		}
		if v1, ok1 := v.([]map[string]interface{}); ok1 {
			d := make([]JObject, 0)
			for k2, v2 := range v1 {
				d[k2] = JObject{data: v2}
			}
			return d, nil
		} else {
			return nil, errors.New("not JObject")
		}
	} else {
		return nil, errors.New("no field")
	}
}

func (o *JObject) GetString(key string) (string, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(string); ok1 {
			return v1, nil
		} else {
			return "", errors.New("not string")
		}
	} else {
		return "", errors.New("no field")
	}
}

func (o *JObject) GetBool(key string) (bool, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(bool); ok1 {
			return v1, nil
		} else {
			return false, errors.New("not bool")
		}
	} else {
		return false, errors.New("no field")
	}
}

func (o *JObject) GetInt64(key string) (int64, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(float64); ok1 {
			return int64(v1), nil
		} else {
			return 0, errors.New("not int64")
		}
	} else {
		return 0, errors.New("no field")
	}
}

func (o *JObject) GetUint64(key string) (uint64, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(float64); ok1 {
			return uint64(v1), nil
		} else {
			return 0, errors.New("not uint64")
		}
	} else {
		return 0, errors.New("no field")
	}
}

func (o *JObject) GetFloat32(key string) (float32, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(float32); ok1 {
			return v1, nil
		} else {
			return 0.0, errors.New("not float32")
		}
	} else {
		return 0.0, errors.New("no field")
	}
}

func (o *JObject) GetFloat64(key string) (float64, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(float64); ok1 {
			return v1, nil
		} else {
			return 0.0, errors.New("not float64")
		}
	} else {
		return 0.0, errors.New("no field")
	}
}

func (o *JObject) GetComplex64(key string) (complex64, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(complex64); ok1 {
			return v1, nil
		} else {
			return 0 + 0i, errors.New("not complex64")
		}
	} else {
		return 0 + 0i, errors.New("no field")
	}
}

func (o *JObject) GetComplex128(key string) (complex128, error) {
	if v, ok := o.data[key]; ok {
		if v1, ok1 := v.(complex128); ok1 {
			return v1, nil
		} else {
			return 0 + 0i, errors.New("not complex128")
		}
	} else {
		return 0 + 0i, errors.New("no field")
	}
}
